<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2025-04-18 08:14:45
// |@----------------------------------------------------------------------
// |@LastEditTime : 2025-05-31 06:59:42
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <topextend@qq.com>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : BlockImage.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2025 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------

declare(strict_types=1);

namespace think\captcha\domain\Logic;

use think\captcha\domain\vo\BackgroundVo;
use think\captcha\domain\vo\ImageVo;
use think\captcha\domain\vo\PointVo;
use think\captcha\domain\vo\TemplateVo;

class BlockImage extends BaseImage
{
    public const WHITE = [255, 255, 255, 1];

    /**
     * @var TemplateVo
     */
    protected $templateVo;

    /**
     * @var TemplateVo
     */
    protected $interfereVo;

    /**
     * @return TemplateVo
     */
    public function getTemplateVo(): TemplateVo
    {
        return $this->templateVo;
    }

    /**
     * @param TemplateVo $templateVo
     * @return self
     */
    public function setTemplateVo(TemplateVo $templateVo): self
    {
        $this->templateVo = $templateVo;
        return $this;
    }

    /**
     * @return TemplateVo
     */
    public function getInterfereVo(): TemplateVo
    {
        return $this->interfereVo;
    }

    /**
     * @param TemplateVo $interfereVo
     * @return static
     */
    public function setInterfereVo(TemplateVo $interfereVo): self
    {

        $this->interfereVo = $interfereVo;
        return $this;
    }

    public function run()
    {
        $flag = false;
        $this->cutByTemplate($this->templateVo, $this->backgroundVo, function ($param) use (&$flag) {
            if (!$flag) {
                //记录第一个点
                $this->setPoint(new PointVo($param[0], 5));//前端已将y值写死
                $flag = true;
            }
        });
        if (!empty($this->interfereVo)) {
            $this->cutByTemplate($this->interfereVo, $this->backgroundVo);
        }
        $this->makeWatermark($this->backgroundVo->image);
    }

    public function cutByTemplate(TemplateVo $templateVo, BackgroundVo $backgroundVo, $callable = null)
    {
        $template = $templateVo->image;
        $width = $template->width();
        $height = $template->height();
        
        // 激进优化：跳跃式处理，只处理关键像素点
        $step = 2; // 跳跃步长，减少50%的像素处理
        $firstCallbackTriggered = false;
        
        for ($x = 0; $x < $width; $x += $step) {
            for ($y = 0; $y < $height; $y += $step) {
                // 背景图对应的坐标
                $bgX = $x + $templateVo->offset->x;
                $bgY = $y + $templateVo->offset->y;
                
                // 快速透明度检查
                $templateRgba = $templateVo->getPickColor($x, $y);
                $isOpacity = $templateRgba[3] > 0.5;
                
                if ($isOpacity) {
                    // 只触发一次回调
                    if (!$firstCallbackTriggered && $callable instanceof \Closure) {
                        $callable([$bgX, $bgY]);
                        $firstCallbackTriggered = true;
                    }
                    
                    // 跳过模糊处理以提升性能
                    // $backgroundVo->vagueImage($bgX, $bgY);
                    
                    // 复制背景像素到模板
                    $bgRgba = $backgroundVo->getPickColor($bgX, $bgY);
                    $templateVo->setPixel($bgRgba, $x, $y);
                    
                    // 填充跳过的像素点
                    if ($x + 1 < $width) {
                        $templateVo->setPixel($bgRgba, $x + 1, $y);
                    }
                    if ($y + 1 < $height) {
                        $templateVo->setPixel($bgRgba, $x, $y + 1);
                    }
                    if ($x + 1 < $width && $y + 1 < $height) {
                        $templateVo->setPixel($bgRgba, $x + 1, $y + 1);
                    }
                }
            }
        }
    }

    /**
     * 把$source的颜色复制到$target上
     * @param ImageVo $source
     * @param ImageVo $target
     */
    protected function copyPickColor(ImageVo $source, $sourceX, $sourceY, ImageVo $target, $targetX, $targetY)
    {
        $bgRgba = $source->getPickColor($sourceX, $sourceY);
        $target->setPixel($bgRgba, $targetX, $targetY);//复制背景图片给模板
    }

    /**
     * 返回前端需要的格式
     * @return false|string[]
     */
    public function response($type = 'background')
    {
        $image = $type == 'background' ? $this->backgroundVo->image : $this->templateVo->image;
        $encodedImage = $image->encode();
        $mediaType = $encodedImage->mediaType();
        $base64Data = base64_encode((string) $encodedImage);
        $result = "data:{$mediaType};base64,{$base64Data}";
        //返回图片base64的第二部分
        return explode(',', $result)[1];
    }

    /**
     * 用来调试
     */
    public function echo($type = 'background')
    {
        $image = $type == 'background' ? $this->backgroundVo->image : $this->templateVo->image;
        die($image->response());
    }
}
